home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / gnulib / dkbtrace / pbmplus / source / pbm / gemtopbm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-10  |  6.1 KB  |  232 lines

  1. /*
  2.  * Convert a GEM .img file to a portable bitmap file.
  3.  *
  4.  * Author: Diomidis D. Spinellis
  5.  * (C) Copyright 1988 Diomidis D. Spinellis.
  6.  *
  7.  * Permission to use, copy, modify, and distribute this software and its
  8.  * documentation for any purpose and without fee is hereby granted,
  9.  * provided that the above copyright notice appear in all copies and that
  10.  * both that copyright notice and this permission notice appear in
  11.  * supporting documentation.
  12.  *
  13.  * This file is provided AS IS with no warranties of any kind.  The author
  14.  * shall have no liability with respect to the infringement of copyrights,
  15.  * trade secrets or any patents by this file or any part thereof.  In no
  16.  * event will the author be liable for any lost revenue or profits or
  17.  * other special, indirect and consequential damages.
  18.  *
  19.  * Comments and additions should be sent to the author:
  20.  *
  21.  *                     Diomidis D. Spinellis
  22.  *                     1 Myrsinis Str.
  23.  *                     GR-145 62 Kifissia
  24.  *                     GREECE
  25.  *
  26.  */
  27.  
  28. #include <assert.h>
  29. #include "pbm.h"
  30.  
  31. /*
  32.  * Handle systems that do CR-LF translation on reading / writing and
  33.  * little endians (some guesswork is involved).
  34.  */
  35. #ifdef MSDOS
  36. #define LITTLE_ENDIAN
  37. #endif /*MSDOS*/
  38. #ifdef xenix
  39. #define LITTLE_ENDIAN
  40. #endif /*xenix*/
  41. #ifdef sun386
  42. #define LITTLE_ENDIAN
  43. #endif /*sun386*/
  44. #ifdef vax
  45. #define LITTLE_ENDIAN
  46. #endif /*vax*/
  47.  
  48.  
  49. /* Seek from current position */
  50. #ifndef SEEK_CUR
  51. #define SEEK_CUR 1
  52. #endif /*SEEK_CUR*/
  53.  
  54. /*
  55.  * File header structure
  56.  */
  57. struct header {
  58.     short           version;/* Image file version */
  59.     unsigned short  hlen;    /* Header length in bytes */
  60.     unsigned short  planes;    /* Number of planes */
  61.     unsigned short  patlen;    /* Pattern definition length (bytes) */
  62.     unsigned short  pxlen;    /* Pixel height (microns) */
  63.     unsigned short  pxht;    /* Pixel height (microns) */
  64.     unsigned short  linewid;/* Scan line width (bytes) */
  65.     unsigned short  nitems;    /* Number of scan line items */
  66. };
  67.  
  68. /*
  69.  * Scan item header
  70.  */
  71. struct line {
  72.     char            d1, d2;    /* Should be 0 */
  73.     char            d3;    /* Should be 0xff */
  74.     char            count;    /* Repetition count */
  75. };
  76.  
  77. char            pattern[256];
  78.  
  79.  
  80. #ifdef LITTLE_ENDIAN
  81. static void byteswap ARGS(( unsigned short* data, int n ));
  82. #endif /*LITTLE_ENDIAN*/
  83.  
  84. void
  85. main(argc, argv)
  86.     int             argc;
  87.     char           *argv[];
  88. {
  89.     int             debug = 0;
  90.     FILE           *f;
  91.     struct header   hd;
  92.     int             x;
  93.     int             i, j, k, l;
  94.     int             c, cc, linerep;
  95.     int        rows, cols;
  96.     bit        *bitrow;
  97.  
  98.     pbm_init( &argc, argv );
  99.  
  100.     /* Check if the compiler alligns structures the way we want */
  101.     if ( sizeof( struct header ) != 16 )
  102.         pm_error( "sizeof( struct header ) != 16 ???" );
  103.  
  104.     if (argc > 1 && !strcmp(argv[1], "-d")) {
  105.         argc--;
  106.         argv[1] = argv[0];
  107.         ++argv;
  108.         ++debug;
  109.     }
  110.  
  111.     if (argc != 2)
  112.         pm_usage("[-d] <gemfile>");
  113.  
  114.     f = pm_openr( argv[1] );
  115.  
  116.     if (fread(&hd, sizeof hd, 1, f) != 1)
  117.         pm_perror( "read" );
  118.  
  119. #ifdef LITTLE_ENDIAN
  120.     byteswap((unsigned short *) &hd, sizeof hd / 2);
  121. #endif /*LITTLE_ENDIAN*/
  122.  
  123.     for ( i = sizeof(struct header); i < hd.hlen; ++i )
  124.         (void) getc(f);
  125.  
  126.     if (debug) {
  127.         pm_message(
  128.             "version %d, hlen %d, planes %d, patlen %d",
  129.                 hd.version, hd.hlen, hd.planes, hd.patlen, 0);
  130.         pm_message(
  131.             "pxlen %d, pxht %d, linewid %d, nitems %d",
  132.             hd.pxlen, hd.pxht, hd.linewid, hd.nitems, 0);
  133.     }
  134.  
  135.     cols = hd.linewid % 8 == 0 ? hd.linewid : hd.linewid + 8 - hd.linewid % 8;
  136.     rows = hd.nitems;
  137.     pbm_writepbminit( stdout, cols, rows, 0 );
  138.     bitrow = pbm_allocrow( cols );
  139.  
  140.     for (i = 0; i < hd.nitems; ) {
  141.         x = 0;
  142.         linerep = 0;
  143.         while (x < hd.linewid) {
  144.             switch (c = getc(f)) {
  145.             case 0x80:    /* Bit String */
  146.                 c = getc(f);    /* Byte count */
  147.                 if (debug)
  148.                     pm_message(
  149.                         "bit string of %d bytes",
  150.                         c );
  151.                 for (j = 0; j < c; ++j) {
  152.                     cc = getc(f);
  153.                     for (k = 0x80; k; k >>= 1) {
  154.                         bitrow[x] = (k & cc) ? PBM_BLACK : PBM_WHITE;
  155.                         ++x;
  156.                     }
  157.                 }
  158.                 break;
  159.             case 0:        /* Pattern run */
  160.                 c = getc(f);    /* Repeat count */
  161.                 if (debug)
  162.                     pm_message(
  163.                         "pattern run of %d repetitions",
  164.                         c );
  165.                                 /* line repeat */
  166.                                 if (c == 0) {
  167.                                         c = getc(f);
  168.                                         if (c != 0x00ff)
  169.                                                 pm_error( "badly formed line repeat" );
  170.                                         linerep = getc(f);
  171.                                         break;
  172.                                 }
  173.                 fread(pattern, 1, hd.patlen, f);
  174.                 for (j = 0; j < c; ++j)
  175.                     for (l = 0; l < hd.patlen; ++l)
  176.                         for (k = 0x80; k; k >>= 1) {
  177.                             bitrow[x] = (k & pattern[l]) ? PBM_BLACK : PBM_WHITE;
  178.                             ++x;
  179.                         }
  180.                 break;
  181.  
  182.             default:    /* Solid run */
  183.                 if (debug)
  184.                     pm_message(
  185.                         "solid run of %d bytes %s",
  186.                         c & 0x7f,
  187.                         c & 0x80 ? "on" : "off" );
  188.                                 /* each byte had eight bits DSB */
  189.                                 l = (c & 0x80) ? PBM_BLACK : PBM_WHITE;
  190.                                 c = (c & 0x7f) * 8;
  191.                                 for (j = 0; j < c; ++j) {
  192.                                         bitrow[x] = l;
  193.                                         ++x;
  194.                                 }
  195.                 break;
  196.  
  197.             case EOF:    /* End of file */
  198.                 pm_error( "end of file reached" );
  199.  
  200.             }
  201.         }
  202.                 if ( debug )
  203.                         pm_message( "EOL" );
  204.                 if ( x != hd.linewid )
  205.                         pm_error( "EOL beyond edge" );
  206.         do {
  207.             pbm_writepbmrow( stdout, bitrow, cols, 0 );
  208.             ++i;
  209.         } while (linerep--);
  210.     }
  211.     pm_close( f );
  212.     pm_close( stdout );
  213.     exit(0);
  214. }
  215.  
  216. #ifdef LITTLE_ENDIAN
  217. static void
  218. byteswap(data, n)
  219.     unsigned short* data;
  220.     int             n;
  221. {
  222.     register        i;
  223.     char           *p, c;
  224.  
  225.     for (i = 0, p = (char *) data; i < n; ++i, ++p) {
  226.         c = *p;
  227.         *p = *(p + 1);
  228.         *++p = c;
  229.     }
  230. }
  231. #endif /*LITTLE_ENDIAN*/
  232.